#include "EditInteractor.h"
#include <SEDebug/Log/Log.h>
#include <SECore/Events/MouseEvent.h>
#include <SECore/Events/KeyBoardEvent.h>
#include <SEEdit/Widget/View.h>
#include <SEEdit/Render/RenderPass/TestRenderPass.h>
#include <SEEdit/Render/RenderPass/GizmoRenderPass.h>
#include <SECore/Events/Input.h>
#include <SECore/CoreApplication.h>
#include <SEEdit/Descriptors/SelectActorDescriptor.h>
#include <SEEdit/Descriptors/ControlBarStateDescriptor.h>
#include <ImGuizmo.h>
#include <SEUi/SEUi.h>
#include <SECore/CoreApplication.h>
#include <SEEdit/Layer/EditLayer.h>

namespace SEngine
{
    void EditInteractor::OnMousePressEvent(MousePressEventPtr event)
    {
        if (event->GetButton() == MouseButton::SE_LEFT) {
            m_isMouseLeftPressed = true;   
        }
        if (event->GetButton() == MouseButton::SE_RIGHT) {
            m_isMouseRightPressed =  true;
        }
    }

    void EditInteractor::OnMouseReleaseEvent(MouseReleaseEventPtr event)
    {
        auto & selectActor = CoreApplication::App().GetDescriptor<SelectActorDescriptor>()->get();
        if (event->GetButton() == MouseButton::SE_LEFT) {
            if (!ImGuizmo::IsUsing()) {
                float x = event->GetXPos();
                float y = event->GetYPos();
                glm::vec4 rect = m_widget.GetRect();
                rect.w -= 40;        // 减去titel高度
                rect.y += 40;
                auto testRenderPass = static_cast<View&>(m_widget).GetRenderer().Descriptor<RenderPass>::GetDescriptor<TestRenderPass>();
                if (testRenderPass) {
                    auto ids = testRenderPass->get().GetID(x - (float)rect.x, (float)rect.w - (y - (float)rect.y), 1, 1);
                    for (auto id : ids) {
                        static_cast<View&>(m_widget).SetSelectActorByID(id);
                    }
                }
                auto gizmoRenderPass =static_cast<View&>(m_widget).GetRenderer().Descriptor<RenderPass>::GetDescriptor<GizmoRenderPass>();
                if (gizmoRenderPass) {
                    auto id = gizmoRenderPass->get().GetID(x - (float)rect.x, (float)rect.w - (y - (float)rect.y));
                    if (id) {
                        static_cast<View&>(m_widget).SetSelectActorByID(id.value());
                    }
                }
            }
            m_isMouseLeftPressed = false;   
        }
        if (event->GetButton() == MouseButton::SE_RIGHT) {
            m_isMouseRightPressed = false;
        }
    }

    void EditInteractor::OnMouseMoveEvent(MouseMoveEventPtr event)
    {
        if (event->GetButton() == MouseButton::SE_RIGHT) {
            const float padding1 = 20.0f;
            const float padding2 = 30.0f;
            auto rect = static_cast<View&>(m_widget).GetRect();
            if (event->GetXPos() <= rect.x + padding1) {
                Input::GetInstance().SignalWarpMouseInWindow.Invoke(rect.x + rect.z - padding2, event->GetYPos());
            }
            if (event->GetXPos() >= (rect.x + rect.z - padding1)) {
                Input::GetInstance().SignalWarpMouseInWindow.Invoke(rect.x + padding2, event->GetYPos());
            }
            if (event->GetYPos() <= rect.y + 20.0f + padding1) {
                Input::GetInstance().SignalWarpMouseInWindow.Invoke(event->GetXPos(), rect.y + rect.w - 20.0f - padding2);
            }
            if (event->GetYPos() >= (rect.y + rect.w - padding1)) {
                Input::GetInstance().SignalWarpMouseInWindow.Invoke(event->GetXPos(), rect.y + padding2);
            }
        }
    }

    void EditInteractor::OnMouseWheelEvent(MouseWheelEventPtr event)
    {

    }

    void EditInteractor::OnKeyPressEvent(KeyPressEventPtr event)
    {
        if (m_isMouseLeftPressed || m_isMouseRightPressed) 
            return;
        auto & state = CoreApplication::App().GetDescriptor<ControlBarStateDescriptor>()->get();
        if (event->GetKey() == 'w') {
            state.gizmoMode = GizmoMode::Translate;
        }
        if (event->GetKey() == 'e') {
            state.gizmoMode = GizmoMode::Scale;
        }
        if (event->GetKey() == 'r') {
            state.gizmoMode = GizmoMode::Rotate;
        }
        if (event->GetKey() == 'f') {
            static_cast<View&>(m_widget).FocusSelectActor();
        }
        if (event->GetKey() == 127) { // delete
            CoreApplication::App().GetEventLoop().SendTask([this](CoreApplication&) {
                static_cast<View&>(m_widget).DeleteSelectActor();
            });
        }
    }

    void EditInteractor::OnKeyReleaseEvent(KeyReleaseEventPtr event)
    {
    }

} // namespace SEngine

